package com.googlecode.dgwt.client.dojo.data.listener;

import com.googlecode.dgwt.client.dojo.data.base.Store;
import com.googlecode.dgwt.client.dojo.data.model.StoreColumn;
import com.googlecode.dgwt.client.dojo.exception.AttachException;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class ProxyListener<Item> implements StoreListener<Item> {

    private AttachListener<Store<Item>> baseListener;
    private DataListener<Item> dataListener;
    private FetchListener<Item> fetchListener;
    private ModelListener<Item> modelListener;

    
    public ProxyListener() {
    }

    public ProxyListener(AttachListener<Store<Item>> listener) {
        setListener(listener);
    }

    
    public void setListener(AttachListener<Store<Item>> listener) {
        baseListener = listener;
        
        if ((Object)listener instanceof DataListener<?>) {
            dataListener = (DataListener<Item>) listener;
        }
        if ((Object)listener instanceof ModelListener<?>) {
            modelListener = (ModelListener<Item>) listener;
        }
        if ((Object)listener instanceof FetchListener<?>) {
            fetchListener = (FetchListener<Item>) listener;
        }
    }

    
    public AttachListener<Store<Item>> getListener() {
        return baseListener;
    }


    @Override
    public void onAttach(Store<Item> store) throws AttachException {
        if (baseListener != null) {
            baseListener.onAttach(store);
        }
    }

    @Override
    public void onDetach(Store<Item> store) {
        if (baseListener != null) {
            baseListener.onDetach(store);
        }
    }

    @Override
    public void onAdd(int index, Item item) {
        if (dataListener != null) {
            dataListener.onAdd(index, item);
        }
    }

    @Override
    public void onRefresh() {
        if (dataListener != null) {
            dataListener.onRefresh();
        }
    }
    
    @Override
    public void onRefreshItem(Item item) {
        if (dataListener != null) {
            dataListener.onRefreshItem(item);
        }
    }

    @Override
    public void onModified(Item item) {
        if (dataListener != null) {
            dataListener.onModified(item);
        }
    }

    @Override
    public void onRemove(int index, Item item) {
        if (dataListener != null) {
            dataListener.onRemove(index, item);
        }
    }

    @Override
    public void onReplace(int index, Item oldItem, Item newItem) {
        if (dataListener != null) {
            dataListener.onReplace(index, oldItem, newItem);
        }
    }

    @Override
    public void onRefreshValue(Item item, int columnIndex) {
        if (dataListener != null) {
            dataListener.onRefreshValue(item, columnIndex);
        }
    }

    @Override
    public void onColumnRefresh(StoreColumn<Item, ?> column) {
        if (modelListener != null) {
            modelListener.onColumnRefresh(column);
        }
    }

    @Override
    public void onColumnAdded(StoreColumn<Item, ?> column) {
        if (modelListener != null) {
            modelListener.onColumnAdded(column);
        }
    }

    @Override
    public void onColumnChanged(StoreColumn<Item, ?> column) {
        if (modelListener != null) {
            modelListener.onColumnChanged(column);
        }
    }

    @Override
    public void onColumnRemoved(StoreColumn<Item, ?> column) {
        if (modelListener != null) {
            modelListener.onColumnRemoved(column);
        }
    }

    @Override
    public void onColumnReplaced(int columnIndex, StoreColumn<Item, ?> oldColumn, StoreColumn<Item, ?> newColumn) {
        if (modelListener != null) {
            modelListener.onColumnReplaced(columnIndex, oldColumn, newColumn);
        }
    }

    @Override
    public void onFetch(int index, Item item) {
        if (fetchListener != null) {
            fetchListener.onFetch(index, item);
        }
    }

    public static <Item> StoreListener<Item> wrap(AttachListener<Store<Item>> listener){
        if ((Object)listener instanceof StoreListener<?>) {
            return (StoreListener<Item>) listener;
        }
        return new ProxyListener<Item>(listener);
    }

    @Override
    public boolean equals(Object obj) {
        if (baseListener != null && baseListener.equals(obj)) {
            return true;
        }
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        return baseListener != null ? baseListener.hashCode() : super.hashCode();
    }

}
